package com.css.fxfzypg.modules.earthquakedisasterloss.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.css.fxfzypg.base.response.RestResponse;
import com.css.fxfzypg.constants.FxfzConstants;
import com.css.fxfzypg.modules.SettingSeismic.entity.SeismicIntensityRelation;
import com.css.fxfzypg.modules.SettingSeismic.repository.IntensityRelationRepository;
import com.css.fxfzypg.modules.SettingSeismic.service.SettingSeismicService;
import com.css.fxfzypg.modules.baseData.entity.*;
import com.css.fxfzypg.modules.baseData.repository.PeoRepository;
import com.css.fxfzypg.modules.earthquakedisasterloss.entity.PlantPbe;
import com.css.fxfzypg.modules.earthquakedisasterloss.service.PopulationCountService;
import com.css.fxfzypg.modules.earthquakedisasterloss.service.YpgResultPbeService;
import com.css.fxfzypg.modules.model.entity.*;
import com.css.fxfzypg.modules.model.repository.CasualtyRepository;
import com.css.fxfzypg.modules.model.repository.ResettlementPersonnelRepository;
import com.css.fxfzypg.modules.model.service.CasualtyService;
import com.css.fxfzypg.modules.preassesstaskmanage.entity.PreAssessTaskEntity;
import com.css.fxfzypg.modules.preassesstaskmanage.service.PreAssessTaskService;
import com.css.fxfzypg.modules.resultupload.repository.entity.ResultDetailsEntity;
import com.css.fxfzypg.modules.resultupload.repository.entity.ResultMainEntity;
import com.css.fxfzypg.modules.resultupload.service.ResultTotalService;
import com.css.fxfzypg.util.*;
import org.geotools.data.FeatureWriter;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.MultiPolygon;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.Charset;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Service
public class PopulationCountServiceImpl implements PopulationCountService {
    @Resource
    private ResettlementPersonnelRepository resettlementPersonnelRepository;
    @Resource
    private PeoRepository peoRepository;
    @Resource
    CasualtyService casualtyService;
    @Resource
    CasualtyRepository casualtyRepository;
    @Resource
    IntensityRelationRepository intensityRelationRepository;
    @Resource
    ResultTotalService resultTotalService;
    @Resource
    YpgResultPbeService ypgResultPbeService;
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    public static final int BATCH_SIZE = 1000;
    @Resource
    PreAssessTaskService preAssessTaskService;
    @Resource
    SettingSeismicService settingSeismicService;

    @Value("${image.localDir}")
    private String localDir;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse AzCount(String mxId, String taskId) {
        RestResponse restResponse = null;
        try {
            if (PlatformObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(taskId))) {
                return RestResponse.fail(503, "该任务的正在被其他人计算，请稍后再操作！！！");
            }
            redisTemplate.opsForValue().set(taskId, "5-1");

            SeismicIntensityRelation byTaskId = intensityRelationRepository.getByTaskId(taskId);
            if (PlatformObjectUtils.isEmpty(byTaskId)) {
                return RestResponse.fail(503, "请重新生成该任务下的地震影响场！");
            }
            ypgResultPbeService.delPlantPbe(taskId);

            //根据模型id查询数据表
            ResettlementPersonnel model = resettlementPersonnelRepository.getModelById(mxId);
            //根据地震影响场id去获取当前公里格网数据
            List<PbeEntity> pbe = ypgResultPbeService.getPbeByTaskId(taskId);
            List<PlantPbe> plantPbeList = new ArrayList<>();
            for (PbeEntity pbeEntity : pbe) {
                for (int i = 6; i < 11; i++) {
                    Float population = pbeEntity.getPopulation();
                    BigDecimal ratio = BigDecimal.ZERO;
                    switch (i) {
                        case 6:
                            ratio = model.getRatio1();
                            break;
                        case 7:
                            ratio = model.getRatio2();
                            break;
                        case 8:
                            ratio = model.getRatio3();
                            break;
                        default:
                            ratio = model.getRatio4();
                            break;
                    }
                    BigDecimal plantPerson = ratio.multiply(new BigDecimal(population)).setScale(2, BigDecimal.ROUND_DOWN);
                    //PlantPbe plantPbe = ypgResultPbeService.savePlantPbe1(taskId, pbeEntity.getPbeId(), pbeEntity.getGeomText(), i, plantPerson);
                    PlantPbe plantPbe = ypgResultPbeService.getNewPlantPbe(taskId, pbeEntity.getPbeId(), pbeEntity.getGeomText(), i, plantPerson);
                    plantPbeList.add(plantPbe);
                }
            }
            //批量插入
            if (plantPbeList.size() > 0) {
                //创建分区表
                ypgResultPbeService.createResultPbeFqRel(taskId);
                System.out.println(plantPbeList.size());
                //一次1000万条
                int fromIndex = 0;
                int toIndex = BATCH_SIZE;
                while (fromIndex != plantPbeList.size()) {
                    if (toIndex > plantPbeList.size()) {
                        toIndex = plantPbeList.size();
                    }
                    List<PlantPbe> list = plantPbeList.subList(fromIndex, toIndex);
                    int insertcount = ypgResultPbeService.savePlantPbeList(list);
                    System.out.println("插入成功" + insertcount);
                    fromIndex = toIndex;
                    toIndex += BATCH_SIZE;
                    if (toIndex > plantPbeList.size())
                        toIndex = plantPbeList.size();
                }
            }
            byTaskId.setModel4Id(model.getId());
            byTaskId.setModel4Type("2");
            byTaskId.setButton4_status1("1");
            byTaskId.setButton4_status2("0");
            byTaskId.setButton6_status1("0");
            intensityRelationRepository.updateSeismicIntensityRelation(byTaskId);
            return RestResponse.succeed("计算成功！");
        } catch (Exception e) {
            e.printStackTrace();
            restResponse = RestResponse.fail("计算失败!");
            return restResponse;
        } finally {
            redisTemplate.delete(taskId);
            if (restResponse != null) {
                if (restResponse.getCode() != 200) {
                    //事务手动回滚
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                }
            }
        }
    }

    private String compareTo(BigDecimal num1, String num2) {
        // num1:5 8 4 3
        // num2:10-0
        String[] split = num2.split("-");//5 10
        for (int i = 0; i < split.length; i++) {
            if (i == 0 && num1.compareTo(new BigDecimal(split[0])) < 0) {
                if (split.length == 2) {
                    if (new BigDecimal(split[0]).compareTo(new BigDecimal(split[1])) > 0) {
                        split[1] = String.valueOf(new BigDecimal(split[0]).intValue());
                        split[0] = String.valueOf(num1.intValue());
                    } else {
                        split[0] = String.valueOf(num1.intValue());
                        split[1] = String.valueOf(new BigDecimal(split[1]).intValue());
                    }
                } else {
                    split[0] = String.valueOf(num1.intValue());
                    split[1] = String.valueOf(new BigDecimal(split[1]).intValue());
                }
            } else if (i == 1 && num1.compareTo(new BigDecimal(split[1])) > 0) {
                split[0] = String.valueOf(new BigDecimal(split[0]).intValue());
                split[1] = String.valueOf(num1.intValue());
            }
        }
        num2 = split[0] + "-" + split[1];
        return num2;
    }

    /**
     * T=(c+d+e/2)*b/a-f
     * 式中，a为户均居住面积，b为户均人口，c 为所有住宅房屋的毁坏面积，d为非简易房屋的严重破坏面积，
     * e为非简易房屋中等破坏面积与简易房屋中等破坏面积之和，f为死亡人数
     * 简易房屋：结构类型为砖木房屋、土结构房屋、木结构房屋、石结构房屋、其他结构，
     * 非简易房屋：高层建筑、钢结构房屋、多层钢筋混凝土房屋、砌体房屋
     */
    List<String> jyfw = Arrays.asList("4", "5", "6", "7", "8");
    List<String> fjyfw = Arrays.asList("0", "1", "2", "3");

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse AzMath(String taskId, String tab,String range) {
        RestResponse restResponse = null;
        try {
            if (PlatformObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(taskId))) {
                return RestResponse.fail(503, "该任务的正在被其他人计算，请稍后再操作！！！");
            }
            redisTemplate.opsForValue().set(taskId, "5-1");
            long start = System.currentTimeMillis();

            SeismicIntensityRelation byTaskId = intensityRelationRepository.getByTaskId(taskId);
            if (PlatformObjectUtils.isEmpty(byTaskId)) {
                return RestResponse.fail(503, "请重新生成该任务下的地震影响场！");
            }

            //修改为查总数
            Integer countTaskPbeByPbeId = casualtyService.getTaskPbeCount(taskId);
            Integer countPbeList = casualtyRepository.getDataPbeIntStrAreaCountByTaskId(taskId, "");

            List<DataPbeInjuriesVo> taskPbeVoByPbeId = casualtyService.getTaskPbeVo(taskId);
            Map<String, BigDecimal> taskPbeVoMap = taskPbeVoByPbeId.stream().collect(Collectors.toMap(DataPbeInjuriesVo::getId, DataPbeInjuriesVo::getDeathNum, (key1, key2) -> key2));
            //List<DataPbeInjuries> taskPbeByPbeId = casualtyService.getTaskPbe(taskId);
            //List<DataPbeIntStrArea> pbeList = casualtyRepository.getDataPbeIntStrAreaByTaskId(taskId, "");
            if (countPbeList <= 0) {
                return RestResponse.fail(503, "请先计算该任务下的人员伤亡！");
            }

            //删除上一次的结果，没有则删除0条
            ypgResultPbeService.delPlantPbe(taskId);

            PreAssessTaskEntity byId = preAssessTaskService.getById(taskId);
            String taskDistrict = byId.getTaskDistrict();

            String province = "", city = "", county = "";
            PeoEntity peoEntity = null;
            List<PlantPbe> plantPbeList = new ArrayList<>();

            int firstIndex = 0;
            int pageSize = 100000;
            if (pageSize > countPbeList){
                pageSize = countPbeList;
            }
            int lastIndex = pageSize;
            while (firstIndex != countPbeList) {
                if (lastIndex > countPbeList) {
                    lastIndex = countPbeList;
                }
                List<DataPbeIntStrArea> pbeList = casualtyRepository.getLimitListByTaskId(taskId, "",firstIndex,pageSize);

                for (int k = 0; k < pbeList.size(); k = k + 25) {
                    DataPbeIntStrArea entity = pbeList.get(k);
                    String type1 = entity.getType1();//0:任务范围内的格网；1:任务范围外，影响场范围内的格网
                    //根据公里格网的省市区获取到人口普查数据
                    if (!province.equals(entity.getProvince()) || !city.equals(entity.getCity()) || !county.equals(entity.getCounty())) {
                        peoEntity = peoRepository.findPeoByProAndCityAndPre(entity.getProvince(), entity.getCity(), entity.getCounty());
                    } else {
                        if (PlatformObjectUtils.isEmpty(peoEntity)) {
                            peoEntity = peoRepository.findPeoByProAndCityAndPre(entity.getProvince(), entity.getCity(), entity.getCounty());
                        }
                    }
                    if (PlatformObjectUtils.isEmpty(peoEntity)) {
                        //tab1为true表示该格网在该任务区域内
                        boolean tab1 = false;
                        for (String s : taskDistrict.split("、")) {
                            if (s.equals(entity.getProvince() + "-" + entity.getCity() + "-" + entity.getCounty())) {
                                tab1 = true;
                                break;
                            } else if (s.equals(entity.getProvince() + "-" + entity.getCity())) {
                                tab1 = true;
                                break;
                            } else if (s.equals(entity.getProvince())) {
                                tab1 = true;
                                break;
                            }
                        }
                        if (tab1 && "0".equals(type1)) {
                            restResponse = RestResponse.fail(503,
                                    "未获取到" + entity.getProvince() + "、" + entity.getCity() + "、" + entity.getCounty() + "的人口普查数据！");
                            return restResponse;
                        } else if ((!tab1 && "0".equals(type1) && !tab.contains("1")) || "1".equals(type1) && !tab.contains("1")) {
                            if (range.equals("0")){
                            JSONObject map = new JSONObject();
                            map.put("tab", tab + "1");
                            restResponse = RestResponse.fail(501, "未获取到" + entity.getProvince() + "、" + entity.getCity() +
                                    "、" + entity.getCounty() + "的人口普查数据,请确认是否继续进行计算！", map);
                            return restResponse;
                            }

                        }
                    }
                    if (PlatformObjectUtils.isEmpty(peoEntity.getPeoAvgArea())) {
                        //tab1为true表示该格网在该任务区域内
                        boolean tab1 = false;
                        for (String s : taskDistrict.split("、")) {
                            if (s.equals(entity.getProvince() + "-" + entity.getCity() + "-" + entity.getCounty())) {
                                tab1 = true;
                                break;
                            } else if (s.equals(entity.getProvince() + "-" + entity.getCity())) {
                                tab1 = true;
                                break;
                            } else if (s.equals(entity.getProvince())) {
                                tab1 = true;
                                break;
                            }
                        }
                        if (tab1 && "0".equals(type1)) {
                            restResponse = RestResponse.fail(503,
                                    "未获取到" + entity.getProvince() + "、" + entity.getCity() + "、" + entity.getCounty() + "的人口普查数据的户均居住面积！");
                            return restResponse;
                        } else if ((!tab1 && "0".equals(type1) && !tab.contains("2")) || "1".equals(type1) && !tab.contains("2")) {
                           if (range.equals("0")){
                                JSONObject map = new JSONObject();
                            map.put("tab", tab + "2");
                            restResponse = RestResponse.fail(501, "未获取到" + entity.getProvince() + "、" + entity.getCity() +
                                    "、" + entity.getCounty() + "的人口普查数据的户均居住面积,请确认是否继续进行计算！", map);
                            return restResponse;
                           }

                        }
                    }
                    //divide为式中的b/a
                    BigDecimal divide = peoEntity.getPeoAvgArea() == null || peoEntity.getPeoAvgArea().compareTo(BigDecimal.ZERO) == 0 ?
                            BigDecimal.ZERO : new BigDecimal(1).divide(peoEntity.getPeoAvgArea(), 10, BigDecimal.ROUND_HALF_UP);

                    for (int i = 6; i < 11; i++) {
                        //所有房屋的毁坏面积
                        BigDecimal sumArea1 = BigDecimal.ZERO;
                        //非简易房屋的严重破坏面积
                        BigDecimal d = BigDecimal.ZERO;
                        //非简易房屋中等破坏面积与简易房屋中等破坏面积之和 e
                        BigDecimal e = BigDecimal.ZERO;
                        for (int j = 0; j < 9; j++) {
                            if (FxfzConstants.HIGH_STRUCTURE.equals(String.valueOf(j))) {
                                //中等破坏
                                e = e.add(pbeList.get(k + (i - 6) * 5 + 2).getHArea());
                                //严重破坏
                                if (fjyfw.contains(String.valueOf(j))) {
                                    d = d.add(pbeList.get(k + (i - 6) * 5 + 3).getHArea());
                                }
                                //损坏
                                sumArea1 = sumArea1.add(pbeList.get(k + (i - 6) * 5 + 4).getHArea());
                            } else if (FxfzConstants.STEEL_STRUCTURE.equals(String.valueOf(j))) {
                                //中等破坏
                                e = e.add(pbeList.get(k + (i - 6) * 5 + 2).getSteelArea());
                                //严重破坏
                                if (fjyfw.contains(String.valueOf(j))) {
                                    d = d.add(pbeList.get(k + (i - 6) * 5 + 3).getSteelArea());
                                }
                                //损坏
                                sumArea1 = sumArea1.add(pbeList.get(k + (i - 6) * 5 + 4).getSteelArea());
                            } else if (FxfzConstants.HNT_STRUCTURE.equals(String.valueOf(j))) {
                                //中等破坏
                                e = e.add(pbeList.get(k + (i - 6) * 5 + 2).getCArea());
                                //严重破坏
                                if (fjyfw.contains(String.valueOf(j))) {
                                    d = d.add(pbeList.get(k + (i - 6) * 5 + 3).getCArea());
                                }
                                //损坏
                                sumArea1 = sumArea1.add(pbeList.get(k + (i - 6) * 5 + 4).getCArea());
                            } else if (FxfzConstants.ZH_STRUCTURE.equals(String.valueOf(j))) {
                                //中等破坏
                                e = e.add(pbeList.get(k + (i - 6) * 5 + 2).getBArea());
                                //严重破坏
                                if (fjyfw.contains(String.valueOf(j))) {
                                    d = d.add(pbeList.get(k + (i - 6) * 5 + 3).getBArea());
                                }
                                //损坏
                                sumArea1 = sumArea1.add(pbeList.get(k + (i - 6) * 5 + 4).getBArea());
                            } else if (FxfzConstants.ZM_STRUCTURE.equals(String.valueOf(j))) {
                                //中等破坏
                                e = e.add(pbeList.get(k + (i - 6) * 5 + 2).getBmArea());
                                //严重破坏
                                if (fjyfw.contains(String.valueOf(j))) {
                                    d = d.add(pbeList.get(k + (i - 6) * 5 + 3).getBmArea());
                                }
                                //损坏
                                sumArea1 = sumArea1.add(pbeList.get(k + (i - 6) * 5 + 4).getBmArea());
                            } else if (FxfzConstants.SOIL_STRUCTURE.equals(String.valueOf(j))) {
                                //中等破坏
                                e = e.add(pbeList.get(k + (i - 6) * 5 + 2).getSArea());
                                //严重破坏
                                if (fjyfw.contains(String.valueOf(j))) {
                                    d = d.add(pbeList.get(k + (i - 6) * 5 + 3).getSArea());
                                }
                                //损坏
                                sumArea1 = sumArea1.add(pbeList.get(k + (i - 6) * 5 + 4).getSArea());
                            } else if (FxfzConstants.WOOD_STRUCTURE.equals(String.valueOf(j))) {
                                //中等破坏
                                e = e.add(pbeList.get(k + (i - 6) * 5 + 2).getWArea());
                                //严重破坏
                                if (fjyfw.contains(String.valueOf(j))) {
                                    d = d.add(pbeList.get(k + (i - 6) * 5 + 3).getWArea());
                                }
                                //损坏
                                sumArea1 = sumArea1.add(pbeList.get(k + (i - 6) * 5 + 4).getWArea());
                            } else if (FxfzConstants.STONE_STRUCTURE.equals(String.valueOf(j))) {
                                //中等破坏
                                e = e.add(pbeList.get(k + (i - 6) * 5 + 2).getStArea());
                                //严重破坏
                                if (fjyfw.contains(String.valueOf(j))) {
                                    d = d.add(pbeList.get(k + (i - 6) * 5 + 3).getStArea());
                                }
                                //损坏
                                sumArea1 = sumArea1.add(pbeList.get(k + (i - 6) * 5 + 4).getStArea());
                            } else if (FxfzConstants.OTHER_STRUCTURE.equals(String.valueOf(j))) {
                                //中等破坏
                                e = e.add(pbeList.get(k + (i - 6) * 5 + 2).getOArea());
                                //严重破坏
                                if (fjyfw.contains(String.valueOf(j))) {
                                    d = d.add(pbeList.get(k + (i - 6) * 5 + 3).getOArea());
                                }
                                //损坏
                                sumArea1 = sumArea1.add(pbeList.get(k + (i - 6) * 5 + 4).getOArea());
                            }
                        }
                        //c 为所有住宅房屋的毁坏面积
                        BigDecimal c = sumArea1.multiply(entity.getDhpHouseTatio()).divide(BigDecimal.valueOf(100), 10,
                                BigDecimal.ROUND_UP);

                        //死亡人数 f
                        BigDecimal f = BigDecimal.ZERO;
                        boolean tab2 = true;
                        String key = entity.getPbeId() + '-' + String.valueOf(i);
                        f = taskPbeVoMap.get(key);
                        if (PlatformObjectUtils.isNotEmpty(f)){
                            tab2 = false;
                        }
                        /*for (DataPbeInjuriesVo dataPbeInjuries : taskPbeVoByPbeId) {
                            if (String.valueOf(i).equals(dataPbeInjuries.getDzIntentity())
                                    && entity.getPbeId().equals(dataPbeInjuries.getPbeId())) {
                                f = dataPbeInjuries.getDeathNum();
                                tab2 = false;
                                break;
                            }
                        }*/
                        if (tab2) {
                            restResponse = RestResponse.fail(503, "未获取到该地震影响场下的公里格网的死亡人数数据！请先计算人员伤亡！");
                            return restResponse;
                        }
                        //每个公里格网的安置人数
                        BigDecimal T = (c.add(d).add(e.divide(BigDecimal.valueOf(2), 8, BigDecimal.ROUND_HALF_UP))).multiply(divide).subtract(f);
                        if (T.compareTo(BigDecimal.ZERO) < 0) {
                            T = BigDecimal.ZERO;
                        }
                        //ypgResultPbeService.savePlantPbe1(taskId, entity.getPbeId(), entity.getGeomText(), i, T);
                        PlantPbe plantPbe = ypgResultPbeService.getNewPlantPbe(taskId, entity.getPbeId(), entity.getGeomText(), i, T);
                        plantPbeList.add(plantPbe);
                    }
                    province = entity.getProvince();
                    city = entity.getCity();
                    county = entity.getCounty();
                }

                firstIndex = lastIndex;
                lastIndex += 100000;
                if (lastIndex > countPbeList)
                    lastIndex = countPbeList;
            }


            //批量插入
            if (plantPbeList.size() > 0) {
                //创建分区表
                ypgResultPbeService.createResultPbeFqRel(taskId);
                System.out.println(plantPbeList.size());
                //一次1000万条
                int fromIndex = 0;
                int toIndex = BATCH_SIZE;
                while (fromIndex != plantPbeList.size()) {
                    if (toIndex > plantPbeList.size()) {
                        toIndex = plantPbeList.size();
                    }
                    List<PlantPbe> list = plantPbeList.subList(fromIndex, toIndex);
                    int insertcount = ypgResultPbeService.savePlantPbeList(list);
                    System.out.println("插入成功" + insertcount);
                    fromIndex = toIndex;
                    toIndex += BATCH_SIZE;
                    if (toIndex > plantPbeList.size())
                        toIndex = plantPbeList.size();
                }
            }
            byTaskId.setModel4Id("1");
            byTaskId.setModel4Type("1");
            byTaskId.setButton4_status1("1");
            byTaskId.setButton4_status2("0");
            byTaskId.setButton6_status1("0");
            intensityRelationRepository.updateSeismicIntensityRelation(byTaskId);
            System.out.println("保存时间:" + (System.currentTimeMillis() - start) / 1000);
            return RestResponse.succeed("计算成功!");
        } catch (Exception e) {
            e.printStackTrace();
            restResponse = RestResponse.fail("计算失败!");
            return restResponse;
        } finally {
            redisTemplate.delete(taskId);
            if (restResponse != null) {
                if (restResponse.getCode() != 200) {
                    //事务手动回滚
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse saveResult(String taskId,String range) {
        RestResponse restResponse = null;
        try {
            if (PlatformObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(taskId))) {
                return RestResponse.fail(503, "该任务的正在被其他人计算，请稍后再操作！！！");
            }
            redisTemplate.opsForValue().set(taskId, "5-2");
            long start = System.currentTimeMillis();
            SeismicIntensityRelation byTaskId = intensityRelationRepository.getByTaskId(taskId);
            if (PlatformObjectUtils.isEmpty(byTaskId)) {
                return RestResponse.fail(503, "请重新生成该任务下的地震影响场！");
            }
            //通过任务id获取到所有点的详情
            List<String> pointDetailList = settingSeismicService.getPointDetailByTaskId(taskId);
            //根据任务id获取任务下的所有的影响场（椭圆）下的同一个地震烈度的格网的人员伤亡数据
            //------------------- 根据任务id  获取任务范围与影响场范围交集部分下的同一个地震烈度的格网的人员伤亡数据
            List<Map<String, Object>> mapList = ypgResultPbeService.getPlantPbeByTaskId(taskId,range);
            //pbeId,area,plantPerson,longitude,latitude,earthquakeLevel,angle,earthquakeId
            if (PlatformObjectUtils.isEmpty(mapList)) {
                // casualtyRepository.deleteByTaskId(taskId);
                return RestResponse.fail(503, "计算失败,该任务尚未生成影响场!");
            }
            //获取到同一个设定地震点下不同影响场的最大相交面积的格网的数据
            Map<String, Map<String, Object>> initMap = initMap1(mapList);
            Map<String, BigDecimal> detailMap = new HashMap<>();
            for (Map.Entry<String, Map<String, Object>> entry : initMap.entrySet()) {
                Map<String, Object> value = entry.getValue();
                //详表
                BigDecimal plantPerson = null;
                String key1 = taskId + "-" + value.get("sort") + "-" + value.get("earthquakeLevel") + "-" + value.get("angle");
                if (detailMap.containsKey(key1)) {
                    plantPerson = detailMap.get(key1);
                    plantPerson = plantPerson.add((BigDecimal) value.get("plantPerson"));//受伤人数和
                } else {
                    //初始化
                    plantPerson = (BigDecimal) value.get("plantPerson");
                }
                detailMap.put(key1, plantPerson);
            }
            Map<String, ResultMainEntity> map = new HashMap<>();
            for (String key : pointDetailList) {
                String[] split = key.split("-");
                ResultDetailsEntity detailsEntity = new ResultDetailsEntity();
                detailsEntity.setTaskId(split[0]);
                detailsEntity.setSort(split[1]);
                detailsEntity.setMagnitude(new BigDecimal(split[2]+""));
                detailsEntity.setAngle(split[3]);

                BigDecimal resettledNum = BigDecimal.ZERO;
                BigDecimal value = detailMap.get(key);
                if (value != null) {
                    resettledNum = value.setScale(0, RoundingMode.HALF_UP);
                }
                detailsEntity.setResettledNum(String.valueOf(resettledNum));
                detailsEntity.setUpdateId(PlatformSessionUtils.getUserId());
                detailsEntity.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
                detailsEntity.setDataSource("2");
                resultTotalService.updateResultDetailsEntity(detailsEntity);

                //结果主表
                String key2 = split[0] + "-" + split[1] + "-" + split[2];
                ResultMainEntity resultMainEntity = null;
                if (map.containsKey(key2)) {
                    resultMainEntity = map.get(key2);
                    resultMainEntity.setResettledNumBefore(compareTo(resettledNum, resultMainEntity.getResettledNumBefore()));
                } else {
                    resultMainEntity = new ResultMainEntity();
                    resultMainEntity.setResettledNumBefore(resettledNum.setScale(0, RoundingMode.HALF_UP) + "-0");
                    map.put(key2, resultMainEntity);
                }
                map.put(key2, resultMainEntity);
            }
            resultTotalService.updateResultMainEntity(map, "4");

            byTaskId.setButton4_status2("1");
            intensityRelationRepository.updateSeismicIntensityRelation(byTaskId);
            System.out.println("计算格网时间花费" + (System.currentTimeMillis() - start) / 1000);
            return RestResponse.succeed("计算成功!");
        } catch (Exception e) {
            e.printStackTrace();
            restResponse = RestResponse.fail("计算失败!");
            return restResponse;
        } finally {
            redisTemplate.delete(taskId);
            if (restResponse != null) {
                if (restResponse.getCode() != 200) {
                    //事务手动回滚
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                }
            }
        }
    }

    private Map<String, Map<String, Object>> initMap1(List<Map<String, Object>> mapList) {
        //pbeId,area,plantPerson,longitude,latitude,earthquakeLevel,angle,earthquakeId
        Map<String, Map<String, Object>> initMap = new HashMap<>();
        for (Map<String, Object> map1 : mapList) {
            String key = map1.get("pbeId") + "-" + map1.get("earthquakeId");
            if (initMap.containsKey(key)) {
                Map<String, Object> map2 = initMap.get(key);
                if (((Double) map2.get("area")).compareTo((Double) map1.get("area")) < 0) {
                    initMap.put(key, map1);
                } else if (((Double) map2.get("area")).compareTo((Double) map1.get("area")) == 0) {
                    if (((BigDecimal) map2.get("earthquakeLevel")).compareTo((BigDecimal) map1.get("earthquakeLevel")) < 0) {
                        initMap.put(key, map1);
                    }
                }
            } else {
                initMap.put(key, map1);
            }
        }
        return initMap;
    }

    // @Override
    // @Transactional(rollbackFor = Exception.class)
    // public RestResponse AzMath(String taskId) {
    //     List<PlantPbe> byTaskId1 = ypgResultPbeService.getByTaskId(taskId);
    //     if (byTaskId1.size() > 0) {
    //         ypgResultPbeService.delPlantPbe(taskId);
    //     }
    //     SeismicIntensityRelation byTaskId = intensityRelationRepository.getByTaskId(taskId);
    //     if (PlatformObjectUtils.isNotEmpty(byTaskId)) {
    //         byTaskId.setModel4Id("1");
    //         byTaskId.setModel4Type("1");
    //         intensityRelationRepository.updateSeismicIntensityRelation(byTaskId);
    //     } else {
    //         return RestResponse.fail("请重新生成该任务下的地震影响场！");
    //     }
    //     Map<String, ResultMainEntity> listMap = new HashMap<>();
    //     //任务id获得地震影响场
    //     List<PointVO> pointVOByTaskId = settingSeismicInfluencefliedRepository.getPointVOByTaskId(taskId);
    //     for (PointVO pointVO : pointVOByTaskId) {
    //         List<SeismicInfluencefliedVO> list1 = settingSeismicInfluencefliedRepository.findByPointVO(taskId, pointVO);
    //         if (list1.size() < 1) {
    //             return RestResponse.fail("请生成该任务下的地震影响场！");
    //         }
    //         for (SeismicInfluencefliedVO s : list1) {
    //             //根据地震影响场id去获取当前公里格网
    //             List<PbeEntity> pbe = pbeService.getPbe2ByInfluenceflieId(s.getInfluencefliedId());
    //             BigDecimal countResPop2 = BigDecimal.ZERO;
    //             for (PbeEntity pbeEntity : pbe) {
    //                 //根据公里格网的省市区获取到人口普查数据
    //                 PeoEntity peoEntity = peoRepository.findPeoByProAndCityAndPre(pbeEntity.getProvince(), pbeEntity.getCity(), pbeEntity.getCounty());
    //                 if (PlatformObjectUtils.isEmpty(peoEntity.getPeoAvgArea())) {
    //                     return RestResponse.fail("未获取到" + pbeEntity.getProvince() + "、" + pbeEntity.getCity() + "、" + pbeEntity.getCounty() + "的人口普查数据的户均居住面积！");
    //                 }
    //                 //divide为式中的b/a
    //                 BigDecimal divide = new BigDecimal(1).divide(peoEntity.getPeoAvgArea(), 10,
    //                         BigDecimal.ROUND_HALF_UP);
    //                 //所有住宅房屋的毁坏面积
    //                 List<CenterResult> centerResultByPbeId =
    //                         casualtyService.getStructureDestoryArea(Collections.singletonList(pbeEntity),s.getDzIntensity(),taskId);
    //                 if (centerResultByPbeId == null || centerResultByPbeId.size() < 1) {
    //                     continue;
    //                     // return RestResponse.fail("未获取到该地震影响场下的公里格网的毁坏面积数据！请先计算人员伤亡！");
    //                 }
    //                 //所有房屋的毁坏面积
    //                 BigDecimal sumArea1 = BigDecimal.ZERO;
    //
    //                 //非简易房屋的严重破坏面积
    //                 BigDecimal d = BigDecimal.ZERO;
    //
    //                 //非简易房屋中等破坏面积与简易房屋中等破坏面积之和 e
    //                 BigDecimal e = BigDecimal.ZERO;
    //
    //                 for (CenterResult cr : centerResultByPbeId) {
    //                     e = e.add(cr.getMidArea());
    //                     sumArea1=sumArea1.add(cr.getSeriousArea());
    //                     if (fjyfw.contains(cr.getStructureType())) {
    //                         d = d.add(cr.getDamageArea());
    //                     }
    //                 }
    //
    //                 //根据公里格网的省市区获取到人口建筑物概况
    //                 HosPeoEntity hosPeoEntity = hosPeoRepository.findHosPeo(pbeEntity.getProvince(), pbeEntity.getCity(), pbeEntity.getCounty());
    //                 if (PlatformObjectUtils.isEmpty(hosPeoEntity.getDhpHouseTatio())) {
    //                     return RestResponse.fail("未获取到" + pbeEntity.getProvince() + "、" + pbeEntity.getCity() + "、" + pbeEntity.getCounty() + "的人口建筑物概况的住宅房屋占比（%）数据！");
    //                 }
    //                 //c 为所有住宅房屋的毁坏面积
    //                 BigDecimal c = sumArea1.multiply(hosPeoEntity.getDhpHouseTatio().divide(BigDecimal.valueOf(100),
    //                         2, BigDecimal.ROUND_UP));
    //
    //                 //死亡人数 f
    //                 List<TaskPbe> taskPbeByPbeId = casualtyService.getTaskPbeByPbeId(taskId, pbeEntity.getPbeId());
    //                 if (taskPbeByPbeId == null || taskPbeByPbeId.size() < 1) {
    //                     // continue;
    //                     return RestResponse.fail("未获取到该地震影响场下的公里格网的死亡人数数据！请先计算人员伤亡！");
    //                 }
    //                 Integer f = taskPbeByPbeId.stream().map(TaskPbe::getDeathPerson).reduce(0, Integer::sum);
    //
    //                 //每个公里格网的安置人数
    //                 BigDecimal T =(c.add(d).add(e.divide(BigDecimal.valueOf(2), 2, BigDecimal.ROUND_HALF_UP))).multiply(divide).subtract(BigDecimal.valueOf(f));
    //                 if (T.compareTo(BigDecimal.ZERO) < 0) {
    //                     T = BigDecimal.ZERO;
    //                 }
    //
    //                 ypgResultPbeService.savePlantPbe(taskId, pbeEntity.getPbeId(), s, T);
    //
    //                 countResPop2 = countResPop2.add(T);
    //             }
    //             ResultDetailsEntity detailsEntity = new ResultDetailsEntity();
    //             detailsEntity.setTaskId(taskId);
    //             detailsEntity.setSort(String.valueOf(s.getFaultNum()));
    //             detailsEntity.setLongitude(String.valueOf(s.getLongitude()));
    //             detailsEntity.setLatitude(String.valueOf(s.getLatitude()));
    //             detailsEntity.setMacroPosition(s.getMacroPosition());
    //             detailsEntity.setMagnitude(s.getEarthquakeLevel());
    //             detailsEntity.setAngle(String.valueOf(s.getAngle()));
    //
    //             BigDecimal resettledNum = countResPop2.setScale(0, RoundingMode.DOWN);
    //             detailsEntity.setResettledNum(String.valueOf(resettledNum.intValue()));
    //             detailsEntity.setResettledNum(String.valueOf(resettledNum.intValue()));
    //
    //             detailsEntity.setUpdateId(PlatformSessionUtils.getUserId());
    //             detailsEntity.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
    //             detailsEntity.setDataSource("2");
    //             //保存
    //             resultTotalService.updateResultDetailsEntity(detailsEntity);
    //
    //             String key = taskId + "-" + s.getFaultNum() + "-" + s.getLongitude() + "-" + s.getLatitude() + "-"
    //                     + s.getMacroPosition() + "-" + s.getEarthquakeLevel() + "-" + "2";
    //             ResultMainEntity resultMainEntity = null;
    //             if (listMap.containsKey(key)) {
    //                 resultMainEntity = listMap.get(key);
    //                 resultMainEntity.setResettledNumBefore(compareTo(resettledNum, resultMainEntity.getResettledNumBefore()));
    //
    //             } else {
    //                 resultMainEntity = new ResultMainEntity();
    //                 resultMainEntity.setResettledNumBefore(resettledNum.intValue() + "-0");
    //                 listMap.put(key, resultMainEntity);
    //             }
    //         }
    //     }
    //     resultTotalService.updateResultMainEntity(listMap, "4");
    //
    //     return ResponseCreator.createSuccessResponse(null, "计算成功！");
    // }
//生成shp文件
    private void buildData( List<PlantPbe> dataList,long postName) throws Exception {
        String filePath = localDir+File.separator+"各个烈度紧急安置人数" +postName+ ".shp";
        File file = new File(filePath);
        ShapefileDataStoreFactory sf = new ShapefileDataStoreFactory();
        ShapefileDataStore ds = (ShapefileDataStore) sf.createDataStore(file.toURI().toURL());
        ds.setCharset(Charset.forName("GBK"));
        SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
        tb.setCRS(CRS.decode("EPSG:4490"));
        tb.setName("shapefile");
        tb.add("烈度", String.class);
        tb.add("安置人数", BigDecimal.class);
        tb.add("the_geom", MultiPolygon.class);
        SimpleFeatureType simpleFeatureType = tb.buildFeatureType();
        ds.createSchema(simpleFeatureType);
        FeatureWriter featureWriter = ds.getFeatureWriter(ds.getTypeNames()[0], null);
        for (PlantPbe seiCapDistribution : dataList) {
            SimpleFeature feature = (SimpleFeature) featureWriter.next();
            feature.setAttribute(1, seiCapDistribution.getDzIntensity());
            feature.setAttribute(2, seiCapDistribution.getPlantPerson());
            String geom =  seiCapDistribution.getGeomText();
            feature.setAttribute("the_geom", geom);
        }
        featureWriter.write();
        featureWriter.close();
        ds.dispose();
    }

    @Override
    public void exportAzrs(String taskId, HttpServletResponse resp) throws Exception{
        List<PlantPbe> dataList = ypgResultPbeService.getPbeByDzIntensity(taskId, "");
        if(PlatformObjectUtils.isEmpty(dataList) || dataList.size()==0){
            throw new RuntimeException("导出失败，未查询到各个烈度下的紧急安置人数数据");
        }
        long postName = System.currentTimeMillis();
        buildData(dataList,postName);
        String zipPath = localDir +File.separator+ "各个烈度紧急安置人数"+System.currentTimeMillis()+ ".zip";
        InputStream input = null;
        ZipOutputStream zipOut = null;

        File zipFile = new File(zipPath);
        try {
            zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
            // zip的名称为
            zipOut.setComment("各个烈度紧急安置人数");
            String[] shpFiles = new String[]{
                    localDir + File.separator  + "各个烈度紧急安置人数"+postName+".dbf",
                    localDir + File.separator  + "各个烈度紧急安置人数"+postName+".prj",
                    localDir + File.separator  + "各个烈度紧急安置人数"+postName+".shp",
                    localDir + File.separator  + "各个烈度紧急安置人数"+postName+".shx",
                    localDir + File.separator  + "各个烈度紧急安置人数"+postName+".fix"
            };
            for (int i = 0; i < shpFiles.length; i++) {
                File file1 = new File(shpFiles[i]);
                input = new FileInputStream(file1);
                zipOut.putNextEntry(new ZipEntry(file1.getName()));
                int temp = 0;
                while ((temp = input.read()) != -1) {
                    zipOut.write(temp);
                }
            }
            for (String shpFile : shpFiles) {
                //删除生成的临时文件
                File file1 = new File(shpFile);
                file1.deleteOnExit();
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (input != null) {
                input.close();
            }
            if (zipOut != null) {
                zipOut.close();
            }
        }
        export(zipFile,resp);
    }

    private void export(File zipFile, HttpServletResponse response) throws IOException {
        InputStream fis = new BufferedInputStream(new FileInputStream(zipFile));
        byte[] buffer = new byte[fis.available()];
        fis.read(buffer);
        fis.close();
        response.reset();
        // 先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,这个文件名称用于浏览器的下载框中自动显示的文件名
        response.setContentType("application/x-msdownload");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(zipFile.getName(), "UTF-8"));
        response.setHeader("Access-Control-Allow-Origin","*");
        OutputStream os = new BufferedOutputStream(response.getOutputStream());
        os.write(buffer);// 输出文件
        os.flush();
        os.close();
    }

    @Override
    public RestResponse getPbeByTaskIdAndIntensity(String taskId, String dzIntensity) {
        // List<PlantPbe> pbeEntityList = new ArrayList<>();
        // List<PlantPbe> byTaskId = ypgResultPbeService.getPbeByDzIntensity(taskId, dzIntensity);
        // Map<String, PlantPbe> map = new HashMap<>();
        // for (PlantPbe plantPbe : byTaskId) {
        //     map.put(plantPbe.getPdeId(), plantPbe);
        // }
        // List<PbeEntity> pbeByTaskId = ypgResultPbeService.getPbeByTaskId(taskId);
        // for (PbeEntity pbeEntity : pbeByTaskId) {
        //     PlantPbe pbeByPbeId = map.get(pbeEntity.getPbeId());
        //     if (PlatformObjectUtils.isEmpty(pbeByPbeId)) {
        //         pbeByPbeId = new PlantPbe();
        //         pbeByPbeId.setPdeId(pbeEntity.getPbeId());
        //         pbeByPbeId.setDzIntensity(dzIntensity);
        //         pbeByPbeId.setTaskId(taskId);
        //         pbeByPbeId.setPlantPerson(BigDecimal.ZERO);
        //     }
        //     pbeByPbeId.setGeomText(pbeEntity.getGeomText());
        //     pbeEntityList.add(pbeByPbeId);
        // }
        List<PlantPbe> byTaskId = ypgResultPbeService.getPbeByDzIntensity(taskId, dzIntensity);
        return RestResponse.succeed(byTaskId);
    }
}
